# -*- coding: utf-8 -*-

import base
import json,uuid,time,traceback,os
import requests,datetime
import pika,logging,sys
from Message.models import *
from Message.tool_qywechat import *
from main.settings import REDIS_STORE_URL,RABBITMQ_HOST_URL,RABBITMQ_USER,RABBITMQ_USER_PASSWORD,RABBITMQ_PORT
# logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# logger = logging.getLogger(__name__)
# from UserPrjConfig.models import Division
class MqConsumer(object):
    """
    构造请求数据
    """
    def __init__(self):
        self.user=RABBITMQ_USER
        self.pwd=RABBITMQ_USER_PASSWORD
        self.host=RABBITMQ_HOST_URL
        self.port=RABBITMQ_PORT
        self.virtual_host='/'
        self.exchange = 'rb-topic'
        self.routing_key = '*.qywechat'
        self.queue='message-qywechat'
    
    #接收消息
    def action(self):
        try:
            # self.linshi_que()
            self.durable_que_topic()
            
        except:
            traceback.print_exc()
    
    def del_quene(self):
        credentials = pika.PlainCredentials(self.user, self.pwd)  # mq用户名和密码
        # 虚拟队列需要指定参数 virtual_host，如果是默认的可以不填。
        connection = pika.BlockingConnection(pika.ConnectionParameters(host = self.host,port = self.port,virtual_host = self.virtual_host,credentials = credentials))
        channel=connection.channel()
        channel.queue_delete(queue=self.queue)
        connection.close()

    def durable_que_topic(self):
        credentials = pika.PlainCredentials(self.user, self.pwd)  # mq用户名和密码
        # 虚拟队列需要指定参数 virtual_host，如果是默认的可以不填。
        connection = pika.BlockingConnection(pika.ConnectionParameters(host = self.host,port = self.port,virtual_host = self.virtual_host,credentials = credentials))
        channel=connection.channel()

        print('self.routing_key----',self.routing_key)

        # 声明exchange，由exchange指定消息在哪个队列传递，如不存在，则创建。durable = True 代表exchange持久化存储，False 非持久化存储
        channel.exchange_declare(exchange = self.exchange,durable = True, exchange_type='topic')

        # 声明消息队列，消息将在这个队列传递，如不存在，则创建。durable = True 代表消息队列持久化存储，False 非持久化存储
        # result = channel.queue_declare(queue = self.queue,durable = True)
        result = channel.queue_declare(queue = self.queue,durable = True)
        
        # 绑定exchange和队列  exchange 使我们能够确切地指定消息应该到哪个队列去
        channel.queue_bind(exchange = self.exchange,queue = self.queue,routing_key=self.routing_key)
        # 定义一个回调函数来处理消息队列中的消息，这里是打印出来
        def callback(ch, method, properties, body):
            ch.basic_ack(delivery_tag = method.delivery_tag)
            # print(u'print-info--',body.decode())
            msg = body.decode()
            curr_routing_key = method.routing_key
            try:
                if not curr_routing_key=='message.qywechat':
                    return
                msg = json.loads(msg)
                projectjson = msg['projectjson']
                msgtype = msg['msgtype']
                messagejson = msg['messagejson']
                touser = msg['touser']
                createtime = msg['createtime']


                obj = {}
                obj['msgtype'] = json.dumps(msgtype)
                obj['messagejson'] = messagejson['articles']
                obj['touser'] = touser
                obj['createtime'] = createtime
                obj['projectjson'] = json.dumps(projectjson)
                currmsg = Message.objects.create(**obj)
                corp_id = projectjson['corp_id']
                secret = projectjson['secret']
                agent_id = msgtype['agent_id']
                redis_url = projectjson['redis_url']
                wca = WeChatClientApi(corp_id,secret,redis_url)
                wechat_client = wca.wechat_client()

                print('articles-----',messagejson['articles'],type(messagejson['articles']))
                if msgtype['type']=='news':
                    currtime = datetime.datetime.now()
                    currtime = currtime.strftime("%Y-%m-%d %H:%M:%S")
                    res = wechat_client.message.send_articles(agent_id, [touser], messagejson['articles'],[], [])
                    currmsg.status = 0
                    currmsg.pushtime = currtime
                    print('res---',res)
                    currmsg.resultinfo = res
                    currmsg.save()
                else:
                    print('其他消息类型发送')
            except :
                print('数据解析异常')
                traceback.print_exc()
            

            
        # 告诉rabbitmq，用callback来接收消息
        channel.basic_consume(self.queue,callback)# 设置成 False，在调用callback函数时，未收到确认标识，消息会重回队列。True，无论调用callback成功与否，消息都被消费掉

        print(u'connecting---',self.queue)
        # 开始接收信息，并进入阻塞状态，队列里有信息才会调用callback进行处理
        channel.start_consuming()
    
    #fanout模式消息
    def durable_que_fanout(self):
        credentials = pika.PlainCredentials(self.user, self.pwd)  # mq用户名和密码
        # 虚拟队列需要指定参数 virtual_host，如果是默认的可以不填。
        connection = pika.BlockingConnection(pika.ConnectionParameters(host = self.host,port = self.port,virtual_host = self.virtual_host,credentials = credentials))
        channel=connection.channel()

        # 声明消息队列，消息将在这个队列传递，如不存在，则创建。durable = True 代表消息队列持久化存储，False 非持久化存储
        result = channel.queue_declare(queue = self.queue,durable = True)

        # 声明exchange，由exchange指定消息在哪个队列传递，如不存在，则创建。durable = True 代表exchange持久化存储，False 非持久化存储
        channel.exchange_declare(exchange = self.exchange,durable = True, exchange_type='fanout')
        # 绑定exchange和队列  exchange 使我们能够确切地指定消息应该到哪个队列去
        channel.queue_bind(exchange = self.exchange,queue = self.queue)
        # 定义一个回调函数来处理消息队列中的消息，这里是打印出来
        def callback(ch, method, properties, body):
            ch.basic_ack(delivery_tag = method.delivery_tag)
            print(u'print-info--',body.decode())
            msg = body.decode()
            # logger.info('exectask----------')
            # logger.info(msg)
            # self.exectask(msg)
            
            obj = {}
            obj['msgtype'] = 'wechat'
            obj['messagejson'] = 'wechat'
            obj['touser'] = 'wechat'
            Message.objects.create(**obj)

        # 告诉rabbitmq，用callback来接收消息
        channel.basic_consume(self.queue,callback)# 设置成 False，在调用callback函数时，未收到确认标识，消息会重回队列。True，无论调用callback成功与否，消息都被消费掉

        print(u'connecting---',self.queue)
        # 开始接收信息，并进入阻塞状态，队列里有信息才会调用callback进行处理
        channel.start_consuming()

    def linshi_que(self):     
        credentials = pika.PlainCredentials(self.user, self.pwd)  # mq用户名和密码
        # 虚拟队列需要指定参数 virtual_host，如果是默认的可以不填。
        connection = pika.BlockingConnection(pika.ConnectionParameters(host = self.host,port = self.port,virtual_host = self.virtual_host,credentials = credentials))
        channel=connection.channel()

        # 申明消息队列，消息在这个队列传递，如果不存在，则创建队列
        # result = channel.queue_declare(queue = self.queue, durable = False)
        
        # 创建临时队列,队列名传空字符，consumer关闭后，队列自动删除
        result = channel.queue_declare('',exclusive=True)

        # 声明exchange，由exchange指定消息在哪个队列传递，如不存在，则创建。durable = True 代表exchange持久化存储，False 非持久化存储
        channel.exchange_declare(exchange = self.exchange,durable = True, exchange_type='fanout')
        # 绑定exchange和队列  exchange 使我们能够确切地指定消息应该到哪个队列去
        channel.queue_bind(exchange = self.exchange,queue = self.queue)
        # 定义一个回调函数来处理消息队列中的消息，这里是打印出来
        def callback(ch, method, properties, body):
            ch.basic_ack(delivery_tag = method.delivery_tag)
            print(u'打印信息--',body.decode())

        # 告诉rabbitmq，用callback来接收消息
        channel.basic_consume(self.queue,callback)# 设置成 False，在调用callback函数时，未收到确认标识，消息会重回队列。True，无论调用callback成功与否，消息都被消费掉

        print(u'已经连接上---',self.queue)
        # 开始接收信息，并进入阻塞状态，队列里有信息才会调用callback进行处理
        channel.start_consuming()
if __name__ == "__main__":
    mqc = MqConsumer()
    mqc.action()
    # mqc.del_quene()



    

    
